home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 2
/
Gold Medal Software Volume 2 (Gold Medal) (1994).iso
/
prog
/
asm_0_m.arj
/
FD.ASM
< prev
next >
Wrap
Assembly Source File
|
1980-01-01
|
13KB
|
410 lines
INCLUDE MACROS.ASM
BEGINCOM FILEDIR
JMP INIT000 ;GO TO INITIALIZATION CODE
;
; FILE DIRECTOR PROGRAM
;
;
;
PATHFLAG DB 0 ;=1=PATH IS AVAILABLE
PATH DB 127 DUP (?) ;FILE PATH
FILENAME DB 64 DUP (?)
CDPREFIX DB 3 DUP (?) ;CURRENT DRIVE PREFIX (IE C:\)
CURDIR DB 64 DUP (?)
CURDRV DB 0 ;CURRENT DRIVE SAVE
SPECTYPE DB 0 ;0=HANDLE, 1 = FCB TYPE I/O
FCBDRIVE DB 0 ;ORIGINAL FCB DRIVE SPECIFIER
AXS DW 0 ;INBOUND REGISTER SAVE AREA
BXS DW 0
CXS DW 0
DXS DW 0
DSS DW 0
ESS DW 0
SIS DW 0
DIS DW 0
;
; SETUP FOR FAKE INTERRUPT INTO DOS
;
DOS LABEL DWORD
DOSOFF DW 0
DOSSEG DW 0
;
; LIST OF THE DOS COMMANDS WE WANT TO TRAP
;
TRAPTABL LABEL BYTE ;DOS CALLS TO TRAP
DB 0FH,01H ; FCB OPEN FILE
;********DB 10H,01H ; FCB CLOSE FILE
DB 3DH,00H ; HANDLE FILE OPEN
TRAPTBLE EQU $ ;END OF TRAP TABLE
PGM_ID DB 'File Director V2.0'
PGM_IDL EQU ($-PGM_ID)
PAGE
;****************************************************************************
;
; File Director Mainline (All DOS interrupts come here)
;
;****************************************************************************
FDIR000:
PUSH DS
PUSH CX
PUSH BX
PUSH AX
PUSH CS
POP DS ;CS AND DS POINT TO THIS SEGMENT
MOV BX,OFFSET TRAPTABL ;POINT TO TABLE OF TRAPS
MOV CX,((TRAPTBLE-TRAPTABL)/2) ;ENTRY COUNT IN TABLE
FDIR020: CMP AH,[BX] ;DOS CALL = TRAP NUMBER?
JE FDIR040 ;YES-WERE OFF AND RUNNING
INC BX
INC BX
LOOP FDIR020 ;CHECK NEXT TRAP
;FALL THRU = PASS CONTROL ON TO DOS
POP AX
POP BX
POP CX
POP DS
JMP CS:DOS ;TRANSFER CONTROL TO DOS
;
; WE HAVE A FILE OPEN COMMAND - LETS FIND THE DAMN FILE
;
FDIR040:
MOV AL,[BX+1] ;SAVE WHETHER FCB OR HANDLE TYPE I/O
MOV SPECTYPE,AL
POP AX
POP BX
POP CX ;LEAVE DS ON STACK
MOV AXS,AX ;SAVE ALL EASILY ACCESSABLE REGS
MOV BXS,BX
MOV CXS,CX
MOV DXS,DX
MOV SIS,SI
MOV DIS,DI
POP AX ;POP INBOUND DS
PUSH AX ;AND THEN PUT IT BACK
MOV DSS,AX ;SAVE IT
MOV AX,ES ;GET INBOUND ES
MOV ESS,AX ;SAVE IT
;
; CHECK DRIVE NUMBER ON FCB REQUEST
;
CMP SPECTYPE,1 ;FCB OPERATION?
JNE FDIR060 ;NO-SKIP THIS
MOV BX,DXS ;GET FCB POINTER
MOV AX,DSS
MOV ES,AX ;ES:BX --> FCB
CMP BYTE PTR ES:[BX],0FFH ;EXTENDED FCB?
JNE FDIR050 ;NO-A REGULAR FCB
ADD BX,7 ;MAKE BX --> DRIVE BYTE
FDIR050: MOV AL,ES:[BX] ;GET DRIVE ASSIGNMENT
MOV FCBDRIVE,AL ;SAVE DRIVE
; ;STACK HAS INBOUND DS ON TOP
;
; SEE IF THE FILE WILL OPEN 'AS IS' (IN THE CURRENT DIRECTORY/PATH)
;
FDIR060:
MOV AX,AXS ;RESTORE DOS COMMAND
POP DS ;RESTORE INBOUND DS
PUSHF ;FAKE AN INTERRUPT INSTR
CALL CS:DOS ;CALL DOS FOR OPEN
PUSH DS ;SAVE INBOUND DS
PUSH AX ;SAVE DOS RETURN VALUE
PUSHF ;SAVE CARRY FLAG FOR HANDLE I/O
PUSH CS
POP DS ;MAKE OUR SEGMENT ADDRESSABLE
CMP PATHFLAG,0 ;IS THERE A PATH TO CHASE?
JE FDIR090 ;NO-RETURN TO APPLICATION
CMP SPECTYPE,0 ;IS THIS A COMMAND TO OPEN WITH A HANDLE
JNE FDIR080 ;NO-ITS AN FCB
;
; HANDLE OPS - INITIAL TRY
;
POPF
PUSHF ;SAVE FLAGS AGAIN
JNC FDIR090 ;IF IT OPENED, GO BACK TO APPLICATION
CMP AX,2 ;FILE NOT FOUND ERROR
JNE FDIR090 ;NO-A DIFFERENT ERROR, RET TO APPLICATION
JMP FDIR100 ;LETS GO INTO THE PATH CHASE CODE
FDIR080:
;
; FCB OPS - INITIAL TRY
;
OR AL,AL ;FILE OPEN OK?
JNZ FDIR400 ;NO-GO TO FCB CHASE
FDIR090: JMP FDIR800 ;** TST ** FOR NOW - JUST ABORT ON FCB'S
PAGE
;****************************************************************************
;
; File Director HANDLE chase code STACK HAS FLAGS, AX, THEN INBOUND DS
;
;****************************************************************************
FDIR100:
POP AX ;REMOVE FLAGS AND AX FROM STACK
POP AX ;LEAVE DS ON THERE
MOV SI,OFFSET PATH
FDIR120: CALL BLDNAME ;BUILD FILENAME IN FILENAME AREA
;
; LETS TRY OPENING WITH THIS PATH
;
MOV DX,OFFSET FILENAME ;DS:DX POINT TO FILENAME
MOV AX,AXS ;GET DOS OPEN COMMAND
PUSHF
CALL DOS ;TRY TO OPEN
PUSH AX
PUSHF ;SAVE DOS RETURNED FLAGS
JNC FDIR190 ;OPENED-RETURN TO APPLICATION
;
; OPEN FAILED - TRY NEXT PATH IF ANY
;
FDIR160: CMP BYTE PTR [SI],0 ;ALL POSSIBILITIES TRIED?
JE FDIR190 ;YES-GIVE UP
INC SI ;ELSE-BUMP PAST SEP CHARACTER
POP AX
POP AX ;POP DOS FLAGS AND RETURN CODE OFF STK
JMP FDIR120 ;AND GO BUILD ANOTHER NAME
FDIR190: POP BX ;POP FLAGS OFF
POP AX ;GET HANDLE OR ERROR CODE
PUSH BX
POPF ;GET OLD FLAGS TO TEST
JNC FDIR195 ;IF NO ERROR-SKIP ALTER ERROR CODE
CMP AX,3 ;INVALID PATH?
JNE FDIR195 ;NO-RETURN TO APPL
DEC AX ;CONVERT TO FILE NOT FOUND
FDIR195: PUSH AX
PUSH BX ;PUSH AX & FLAGS BACK
JMP FDIR800 ;RETURN TO APPLICATION
;****************************************************************************
;
; File Director FCB chase code STACK HAS FLAGS, AX, THEN INBOUND DS
;
;****************************************************************************
FDIR400:
FDIR410: CMP FCBDRIVE,0 ;GENERIC DRIVE REQUEST?
JE FDIR420 ;YES-GO CHASE IT
JMP FDIR800 ;SPECIFIC DRIVE REQUESTED-RETURN ERROR
;
;
;
FDIR420: POPF
POP AX ;REMOVE FLAGS & RET CODE FROM STACK
MOV SI,OFFSET PATH
FDIR440: CALL BLDPATH ;SET UP A NEW PATH
MOV BX,WORD PTR FILENAME
MOV WORD PTR CDPREFIX,BX ;COPY PREFIX
MOV CDPREFIX+2,'\' ;CURRENT DIRECTORY PREFIX SET UP
MOV DL,FILENAME ;GET DRIVE LETTER
SUB DL,'A' ;INDEX (A=1,B=2,ETC)
INC DL
PUSH SI ;SAVE PATH POINTER
MOV SI,OFFSET CURDIR ;CURRENT DIRECTORY SAVE AREA
MOV AH,47H ;GET CURRENT DIRECTORY COMMAND
PUSHF ;FAKE AN INTERRUPT
CALL CS:DOS ;CALL DOS FOR THIS
; ;CURRENT DIRECTORY IS AT CURDIR FOR RESTORE
POP SI ;RESTORE PATH POINTER
MOV DX,OFFSET FILENAME ;POINT TO FILE NAME AREA (CONTAINS PATH)
MOV AH,3BH ;CHANGE CURRENT DIRECTORY
PUSHF ;FAKE AN INTERRUPT
CALL CS:DOS ;CALL DOS FOR THIS
JC FDIR500 ;IF ERROR-TRY NEXT PATH
MOV BX,DXS ;GET FCB POINTER
MOV AX,DSS
MOV ES,AX ;ES:BX --> FCB
CMP BYTE PTR ES:[BX],0FFH ;EXTENDED FCB?
JNE FDIR450 ;NO-A REGULAR FCB
ADD BX,7 ;MAKE BX --> DRIVE BYTE
FDIR450:
MOV AL,FILENAME ;GET DRIVE LETTER FOR THIS PATH
SUB AL,'A' ;FIX UP FOR CHARACTER FORMAT
INC AL ;+1 SINCE DRIVE A = 1
MOV BYTE PTR ES:[BX],AL ;RESET DRIVE BASED ON PATH
MOV AX,AXS ;GET DOS COMMAND
MOV DX,DXS
POP DS ;DS:DS --> FCB
PUSHF ;FAKE AN INT INSTRUCTION
CALL CS:DOS ;TRY TO OPEN
PUSH DS
PUSH AX
PUSHF ;SAVE REGS FOR RETURNING
PUSH CS
POP DS ;RESTORE OUR OWN DS
CMP AL,0 ;OPEN OK?
JE FDIR600 ;YES-APPLICATION RETURN
;
; OPEN FAILED - TRY NEXT PATH
;
FDIR500: CMP BYTE PTR [SI],0 ;HAVE ALL PATHS BEEN SEARCHED?
JE FDIR600 ;YES RETURN TO APPL
; ;RESTORE THE OLD 'CURRENT DIRECTORY'
MOV DX,OFFSET CDPREFIX ;POINT TO SAVED CURRENT DIRECTORY INFO
MOV AH,3BH ;CHANGE CURRENT DIRECTORY
PUSHF ;FAKE AN INTERRUPT
CALL CS:DOS ;CALL DOS FOR THIS
INC SI ;PAST SEPERATOR CHAR
POP AX
POP AX ;REMOVE FLAGS & AX FROM STACK
JMP FDIR440 ;AND TRY ANOTHER PATH
;
; RESET THE ORIGINAL DIRECTORY IN USE BEFORE FILE OPENED
;
FDIR600:
MOV DX,OFFSET CDPREFIX ;POINT TO SAVED CURRENT DIRECTORY INFO
MOV AH,3BH ;CHANGE CURRENT DIRECTORY
PUSHF ;FAKE AN INTERRUPT
CALL CS:DOS ;CALL DOS FOR THIS
;
;
; RETURN TO APPLICATION WHETHER SUCESSFUL OR NOT
;
FDIR800: ;RETURN TO APPLICATION AFTER SEARCH
;
; RETURN TO APPLICATION
;
MOV AX,ESS
MOV ES,AX
MOV BX,BXS
MOV CX,CXS
MOV DX,DXS
MOV SI,SIS
MOV DI,DIS ;RESTORE BX,CX,DX,SI,DI
POPF ;RESTORE DOS RETURN FLAGS
POP AX ;RESTORE DOS RETURN CODE/HANDLE
POP DS ;POP USERS DS
DUMMY PROC FAR
RET 2 ;RETURN TO APPLICATION W/ DOS FLAGS
DUMMY ENDP
PAGE
;******************************************************************************
;
; BUILD FILE NAME IN FILENAME AREA. SI POINTS TO CURRENT SPOT IN PATH LIST
;
;******************************************************************************
BLDNAME PROC NEAR
CALL BLDPATH
; NEW PATH BUILT, APPEND FILE NAME
;
DEC DI ;POINT TO LAST PATH CHARACTER
CMP BYTE PTR [DI],'\' ;IS THERE A SEPERATOR?
JE BLDN120 ;YES-THEN READY FOR FILE NAME
INC DI
MOV BYTE PTR [DI],'\' ;ELSE-INSTALL SEPERATOR
BLDN120: INC DI ;POINT TO NEXT AVAILABLE FILENAME BYTE
MOV BX,DXS ;BX HAS OFFSET OF FILE NAME
MOV AX,DSS ;GET INBOUND DS
MOV ES,AX ;INTO ES
BLDN140: MOV AL,ES:[BX] ;GET CHAR FROM FILE NAME
MOV [DI],AL ;SAVE FOLLOWING THE NEW PATH
INC BX
INC DI ;BUMP POINTERS
CMP AL,0 ;AT END OF FILENAME?
JNE BLDN140 ;NO-KEEP MOVING
RET
BLDNAME ENDP
;
;
;
BLDPATH PROC NEAR
BLDN100: MOV DI,OFFSET FILENAME
BLDP120: MOV AL,[SI] ;GET A PATH CHARACTER
CMP AL,';' ;PATH COMPLETE?
JE BLDP140 ;YES-TRY OPENING UP
CMP AL,0 ;END OF POSSIBLE PATHS
JE BLDP140 ;YES-TRY OPEN (LAST POSSIBLE TRY)
MOV [DI],AL ;SAVE PATH CHARACTER
INC DI
INC SI
JMP BLDP120 ;BUILD COMPLETE PATH
BLDP140: MOV BYTE PTR [DI],0 ;NOW HAVE AN ASCIIZ PATH
RET
BLDPATH ENDP
ENDRES EQU $
PAGE
;
; NON-RESIDENT CODE
;
DONEMSG DB 13,10,'FILE-DIRECTOR PATH SET UP',13,10,'$'
PATHMSG DB 13,10,'CURRENT PATH:',13,10,'$'
NONEMSG DB '==NONE==',13,10,'$'
RESFLAG DB 0 ;ASSUME ALREADY RESIDENT
INIT000:
@DOS 35H,21H ;GET DOS'S OWN INTERRUPT VECTOR
MOV DI,OFFSET PGM_ID ;POINT TO NAME IN RESIDENT PGM (IF ANY)
MOV SI,DI ;OFFSET THE SAME IN THIS PROGRAM
MOV CX,PGM_IDL ;LENGTH TO COMPARE
REP CMPSB ;IS FILE DIRECTOR RESIDENT?
JE INIT100 ;YES-DONT KEEP RESIDENT
PUSH DS
POP ES ;RESTORE ES POINTING TO THIS SEGMENT
MOV RESFLAG,1 ;NOT RESIDENT - POINTERS ARE SET UP TO LOAD
INIT100:
SUB DX,DX ;ACTUAL CHARACTER COUNT
MOV SI,80H ;ADDRESS OF PARM LENGTH COUNT
SUB CH,CH
MOV CL,[SI] ;BYTES TO MOVE
MOV DI,OFFSET PATH ;POINT TO INPUT PATH ES POINTS TO STORAGE
OR CX,CX ;ANY BYTES INPUT?
JZ INIT920 ;NO-DISPLAY PATH
INIT120: INC SI ;POINT TO CHARACTER TO MOVE
MOV AL,[SI] ;GET A CHAR
CMP AL,' ' ;BLANK?
JE INIT140 ;YES-DISCARD
MOV ES:[DI],AL ;ELSE-SAVE IT
INC DI ;BUMP 'FROM' POINTER
INC DX ;CHARACTER MOVED COUNTER
INIT140:
LOOP INIT120
OR DX,DX ;ALL BLANK?
JZ INIT920 ;YES-DISPLAY PATH
MOV ES:PATHFLAG,1 ;ASSUME VALID PATH
CMP DL,1 ;SINGLE CHARACTER?
JNE INIT160 ;NO-THEN PROBABLY A GOOD PATH
CMP AL,';' ;SINGLE SEMICOLON?
JNE INIT160 ;NO-AN INVALID BUT ACCEPTABLE PATH
MOV ES:PATHFLAG,0 ;SET NO PATH AVAILABLE
INIT160:
JZ INIT920 ;YES-DISPLAY CURRENT PATH
MOV BYTE PTR ES:[DI],0 ;MAKE IT AN ASCIIZ STRING
MOV DX,OFFSET DONEMSG
@DOS 9 ;SEND DONE MESSAGE
CMP RESFLAG,1 ;NEED TO KEEP IN CORE?
JE INIT400 ;YES-SET DOS INTERRUPT VECTOR
INT 20H ;ELSE - JUST SAY GOODBYE
INIT400: SUB AX,AX
MOV ES,AX ;ADDRESS LO CORE (DONT CHANGE INT 21 W/DOS)
MOV BX,21H*4 ;ES:BX --> VECTOR FOR DOS
MOV AX,ES:[BX] ;GET DOS'S OFFSET
MOV DOSOFF,AX
MOV AX,ES:[BX+2] ;GET DOS'S SEGMENT
MOV DOSSEG,AX ;POINTER INTO DOS IS SET
MOV AX,OFFSET FDIR000 ;OFFSET TO THE FILE DIRECTOR MAINLINE
CLI ;CANT HAVE INTS DURING VECTOR UPDATE
MOV ES:[BX],AX ;UPDATE DOS OFFSETT
MOV AX,CS ;NEW SEGMENT FOR DOS INT 21H
MOV ES:[BX+2],AX ;UPDATE DOS SEGMENT
STI ;INTS OK NOW
MOV DX,OFFSET ENDRES ;POINT TO END OF RESIDENT CODE
INIT900: INT 27H ;STAY RESIDENT
;
; DISPLAY CURRENT PATH ES:DI --> PATH
;
INIT920: MOV DX,OFFSET PATHMSG
@DOS 9
MOV AL,ES:PATHFLAG ;IS THERE A PATH
OR AL,AL
JNZ INIT930 ;YES-DISPLAY IT
MOV DX,OFFSET NONEMSG
@DOS 9 ;DISPLAY '==NONE=='
INT 20H ;ABORT
INIT930: MOV DL,ES:[DI] ;GET PATH CHARACTER
OR DL,DL ;END?
JZ INIT960 ;YES-APPEND CR/LF
@DOS 2 ;DISPLAY CHAR
INC DI
JMP INIT930 ;DO NEXT
INIT960: MOV DL,13 ;ADD CR/LF
@DOS 2
MOV DL,10
@DOS 2
INT 20H ;ALL DONE
ENDCOM FILEDIR